﻿#include "cat-bake-end.hpp"

#include "../../libcat/include/header/cat-config.hpp"
#include "../../libcat/include/cat-interaction.hpp"
#include "../../libcat/include/cat-data.hpp"
#include "../../libcat/include/cat-hook.hpp"
#include "../../libcat/include/cat-signal.hpp"
#include "../../libcat/include/util/base.hpp"
#include "../../libcat/include/util/platform.hpp"
#include "../../liblive2d/include/catlive2d.hpp"

#include <string>
#include <corecrt_io.h>
#include <windows.h>
#include <SFML\System\Clock.hpp>

using namespace std;

namespace {

	enum CatAction {
		Update = 1,
		Reload,
		ModeChange,
		BakeColorChange,
		WindowChange,
		HeartBeat,
		DisConnect,
		ShowCat,
		HideCat,
		ToolWindow
	};

	static void GetModulelName(const char* filePath)
	{
		string _filepath = filePath;
		_filepath += "/*.dll";

		struct _finddata_t fileInfo;
		long long findResult = _findfirst(_filepath.c_str(), &fileInfo);
		if (findResult == -1) {
			_findclose(findResult);
			return;
		}

		do
		{
			string dllpath = string(filePath) + "/" + +fileInfo.name;
			cat_add_module_path(dllpath.c_str(), "data");
		} while (_findnext(findResult, &fileInfo) == 0);

		_findclose(findResult);
	}

	static void OnInit() {
		/***********设置字体*************/

		cat_set_cat_font(u8"Resources/local/cat.ttf");

		/***********模块加载*************/

		//添加模块路径
		GetModulelName("plugins");
		//加载dll到内存
		cat_load_all_module_from_path();
		//读取dll的信息
		cat_load_all_module_info();		

		//todo: 往config文件写入module信息
		cat_data_write_json_file(cat_load_default_config(), cat_get_default_config_path());

#ifdef _DEBUG		
		//打印已经加载的dll信息
		cat_log_loaded_modules();
#endif // DEBUG

		//update_config_from_config_file(cat_get_default_config_path());

		//update_buffer_config_from_config();

		/***********根据配置初始化模块*************/
		int modeid = cat_get_curent_mode_id();
		cat_init_mode(modeid);

		//其他的模块根据自己的配置加载
		cat_init_input();
		cat_init_ui();
		cat_init_output(); 
		
		cat_push_signal(UIWM_UPDATE);
		cat_push_signal(UIWM_WINDOWCHANGE);
	}

	static void OnDraw() {

		cat_run_input();
		//这里处理所有模块的run方法
		int modeid = cat_get_curent_mode_id();
		cat_run_mode(modeid);
		cat_run_ui();
		cat_run_output();

	}	
}

bool CatBakeEnd::BakeEndInit(char* config)
{
	bool ret = false;
	const char* config_data = NULL;
	if (IsFileExist("config.ini")) {
		config_data = LoadFileAsBytes("config.ini");
	}
	else if (config)
		config_data = config;
	else {
		blog(LOG_ERROR, "Can't Find Config file");
		return false;
	}

	if (cat_startup("config.ini", config_data))
		blog(LOG_DEBUG, "Initialize Bongo Cat success");
	else
	{
		blog(LOG_ERROR, "Can't initialize Bongo Cat");
		return false;
	}

	//设置打开gui的初始化函数
	cat_set_on_init(OnInit);
	//设置画图需要调用的函数
	cat_set_draw_func(OnDraw);

	//初始化里live2d运行环境
	ret =cat_live2d_initailize();

	std::string version = u8"Bongo Cat w ";
	version+=cat_get_version_string();

	if (!cat_open_gui(version.c_str(), "Resources/bongocat.png"))
	{
		blog(LOG_ERROR, "Can't open gui");
		ret = false;
	}
	
	return ret;
}

static char _data[4096];

static void Update_Buffer(char* data, unsigned int size) {	
	memcpy(_data, data, size);
	_data[size] = 0x00;
	cat_data_t* newData = cat_data_create_from_json(_data);

	update_buffer_config_from_data(newData);

	cat_data_release(newData);
}

void CatBakeEnd::DataExchange(int action, char* data, unsigned int size)
{
	/*
	enum CatAction {
		Update=1,
		Reload,	
		ModeChange,
		BakeColorChange, 	
		HeartBeat,
		DisConnect,
	};
	
	*/
	switch (action) {
		case Update: {
			//更新配置
			Update_Buffer(data, size);
			cat_push_signal(UIWM_UPDATE);			
			break;
		}
		case Reload:
		{
			Update_Buffer(data, size); 
			cat_push_signal(UIWM_RELOAD);
			break;
		}
		case ModeChange:
		{
			//模式切换
			Update_Buffer(data, size);
			cat_push_signal(UIWM_MODECHANGE);
			break;
		}	
		case BakeColorChange:
		{
			//设置背景颜色
			Update_Buffer(data, size);
			cat_push_signal(UIWM_BAKECOLORCHANGE);
			break;
		}
		case WindowChange: {
			Update_Buffer(data, size); 
			cat_push_signal(UIWM_WINDOWCHANGE);
			break;
		}
		case HeartBeat:
		{
			//心跳包
			break;
			
		}
		case DisConnect:
		{
			//连接断开
			cat_data_write_json_file(cat_load_default_config(), "config.ini");
			cat_close_gui();
			break;
		}
		case ShowCat: 
		{
			cat_set_gui_visible(true);
			break;
		}
		case HideCat:
		{
			cat_set_gui_visible(false);
			break;
		}
		case ToolWindow: {			
			
			Update_Buffer(data, size);
			cat_push_signal(UIWM_DOCKINGTOOLWINDOW);
		}

	}
}

void CatBakeEnd::ShowWindow(bool _vis)
{
	cat_set_gui_visible(_vis);
}

bool CatBakeEnd::BakeEndRun()
{
	cat_draw_cat();
	return cat_display_gui();
}

void CatBakeEnd::BakeEndRelease()
{
	cat_data_write_json_file(cat_load_default_config(), "config.ini");

	int modeid = cat_get_curent_mode_id();
	cat_release_mode(modeid);

	cat_release_input();
	cat_release_ui();
	cat_release_output();

	cat_live2d_release();
	cat_release_all_module();
	cat_shutdown();
	return;
}

